home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / src / dialog.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-03-03  |  46.8 KB  |  1,804 lines

  1. /* dialog.c - dialog windows for internal use
  2.  * 
  3.  *  Window Maker window manager
  4.  * 
  5.  *  Copyright (c) 1997, 1998 Alfredo K. Kojima
  6.  *  Copyright (c) 1999       Dan Pascu
  7.  * 
  8.  *  This program is free software; you can redistribute it and/or modify
  9.  *  it under the terms of the GNU General Public License as published by
  10.  *  the Free Software Foundation; either version 2 of the License, or
  11.  *  (at your option) any later version.
  12.  *
  13.  *  This program is distributed in the hope that it will be useful,
  14.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.  *  GNU General Public License for more details.
  17.  *
  18.  *  You should have received a copy of the GNU General Public License
  19.  *  along with this program; if not, write to the Free Software
  20.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
  21.  *  USA.
  22.  */
  23.  
  24. #include "wconfig.h"
  25.  
  26. #include <X11/Xlib.h>
  27. #include <X11/Xutil.h>
  28. #include <X11/keysym.h>
  29.  
  30. #include <stdlib.h>
  31. #include <stdio.h>
  32. #include <unistd.h>
  33. #include <string.h>
  34. #include <sys/types.h>
  35. #include <sys/stat.h>
  36. #include <dirent.h>
  37. #include <limits.h>
  38.  
  39. #include <signal.h>
  40. #ifdef __FreeBSD__
  41. #include <sys/signal.h>
  42. #endif
  43.  
  44.  
  45. #ifndef PATH_MAX
  46. #define PATH_MAX DEFAULT_PATH_MAX
  47. #endif
  48.  
  49. #include "WindowMaker.h"
  50. #include "GNUstep.h"
  51. #include "screen.h"
  52. #include "dialog.h"
  53. #include "funcs.h"
  54. #include "stacking.h"
  55. #include "framewin.h"
  56. #include "window.h"
  57. #include "actions.h"
  58. #include "defaults.h"
  59.  
  60.  
  61. extern WPreferences wPreferences;
  62.  
  63.  
  64.  
  65. int
  66. wMessageDialog(WScreen *scr, char *title, char *message, 
  67.            char *defBtn, char *altBtn, char *othBtn)
  68. {
  69.     WMAlertPanel *panel;
  70.     Window parent;
  71.     WWindow *wwin;
  72.     int result;
  73.  
  74.     panel = WMCreateAlertPanel(scr->wmscreen, NULL, title, message,
  75.                    defBtn, altBtn, othBtn);    
  76.  
  77.     parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 400, 180, 0, 0, 0);
  78.     
  79.     XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
  80.  
  81.     wwin = wManageInternalWindow(scr, parent, None, NULL, 
  82.                  (scr->scr_width - 400)/2,
  83.                  (scr->scr_height - 180)/2, 400, 180);
  84.     wwin->client_leader = WMWidgetXID(panel->win);
  85.  
  86.     WMMapWidget(panel->win);
  87.     
  88.     wWindowMap(wwin);
  89.  
  90.     while (!panel->done) {
  91.     XEvent event;
  92.     
  93.     WMNextEvent(dpy, &event);
  94.     WMHandleEvent(&event);
  95.     }
  96.  
  97.     result = panel->result;
  98.  
  99.     WMUnmapWidget(panel->win);
  100.  
  101.     wUnmanageWindow(wwin, False, False);
  102.  
  103.     WMDestroyAlertPanel(panel);
  104.  
  105.     XDestroyWindow(dpy, parent);
  106.  
  107.     return result;
  108. }
  109.  
  110.  
  111.  
  112. int
  113. wInputDialog(WScreen *scr, char *title, char *message, char **text)
  114. {
  115.     WWindow *wwin;
  116.     Window parent;
  117.     WMInputPanel *panel;
  118.     char *result;
  119.  
  120.     
  121.     panel = WMCreateInputPanel(scr->wmscreen, NULL, title, message, *text,
  122.                    _("OK"), _("Cancel"));
  123.  
  124.  
  125.     parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 320, 160, 0, 0, 0);
  126.     XSelectInput(dpy, parent, KeyPressMask|KeyReleaseMask);
  127.  
  128.     XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
  129.  
  130.     wwin = wManageInternalWindow(scr, parent, None, NULL, 
  131.                  (scr->scr_width - 320)/2,
  132.                  (scr->scr_height - 160)/2, 320, 160);
  133.  
  134.     wwin->client_leader = WMWidgetXID(panel->win);
  135.  
  136.     WMMapWidget(panel->win);
  137.     
  138.     wWindowMap(wwin);
  139.     
  140.     while (!panel->done) {
  141.     XEvent event;
  142.     
  143.     WMNextEvent(dpy, &event);
  144.     WMHandleEvent(&event);
  145.     }
  146.     
  147.     if (panel->result == WAPRDefault)
  148.     result = WMGetTextFieldText(panel->text);
  149.     else
  150.     result = NULL;
  151.     
  152.     wUnmanageWindow(wwin, False, False);
  153.     
  154.     WMDestroyInputPanel(panel);
  155.  
  156.     XDestroyWindow(dpy, parent);
  157.  
  158.     if (result==NULL)
  159.     return False;
  160.     else {
  161.         if (*text)
  162.             free(*text);
  163.         *text = result;
  164.  
  165.         return True;
  166.     }
  167. }
  168.  
  169.  
  170. /*
  171.  *****************************************************************
  172.  * Icon Selection Panel
  173.  *****************************************************************
  174.  */
  175.  
  176. typedef struct IconPanel {
  177.     
  178.     WScreen *scr;
  179.     
  180.     WMWindow *win;
  181.  
  182.     WMLabel *dirLabel;
  183.     WMLabel *iconLabel;
  184.     
  185.     WMList *dirList;
  186.     WMList *iconList;
  187.     WMFont *normalfont;
  188.     
  189.     WMButton *previewButton;
  190.  
  191.     WMLabel *iconView;
  192.     
  193.     WMLabel *fileLabel;
  194.     WMTextField *fileField;
  195.     
  196.     WMButton *okButton;
  197.     WMButton *cancelButton;
  198. #if 0
  199.     WMButton *chooseButton;
  200. #endif
  201.     short done;
  202.     short result;
  203.     short preview;
  204. } IconPanel;
  205.  
  206.  
  207.  
  208. static void
  209. listPixmaps(WScreen *scr, WMList *lPtr, char *path)
  210. {
  211.     struct dirent *dentry;
  212.     DIR *dir;
  213.     char pbuf[PATH_MAX+16];
  214.     char *apath;
  215.     IconPanel *panel = WMGetHangedData(lPtr);
  216.  
  217.     panel->preview = False;
  218.     
  219.     apath = wexpandpath(path);
  220.     dir = opendir(apath);
  221.     
  222.     if (!dir) {
  223.     char *msg;
  224.     char *tmp;
  225.     tmp = _("Could not open directory ");
  226.     msg = wmalloc(strlen(tmp)+strlen(path)+6);
  227.     strcpy(msg, tmp);
  228.     strcat(msg, path);
  229.     
  230.     wMessageDialog(scr, _("Error"), msg, _("OK"), NULL, NULL);
  231.     free(msg);
  232.     free(apath);
  233.     return;
  234.     }
  235.  
  236.     /* list contents in the column */
  237.     while ((dentry = readdir(dir))) {
  238.     struct stat statb;
  239.     
  240.     if (strcmp(dentry->d_name, ".")==0 ||
  241.         strcmp(dentry->d_name, "..")==0)
  242.         continue;
  243.  
  244.     strcpy(pbuf, apath);
  245.     strcat(pbuf, "/");
  246.     strcat(pbuf, dentry->d_name);
  247.     
  248.     if (stat(pbuf, &statb)<0)
  249.         continue;
  250.     
  251.     if (statb.st_mode & (S_IRUSR|S_IRGRP|S_IROTH)
  252.         && statb.st_mode & (S_IFREG|S_IFLNK)) {
  253.         WMAddListItem(lPtr, dentry->d_name);
  254.     }
  255.     }
  256.     WMSortListItems(lPtr);
  257.  
  258.     closedir(dir);
  259.     free(apath);
  260.     panel->preview = True;
  261. }
  262.  
  263.  
  264.  
  265. static void
  266. setViewedImage(IconPanel *panel, char *file)
  267. {
  268.     WMPixmap *pixmap;
  269.     RColor color;
  270.         
  271.     color.red = 0xae;
  272.     color.green = 0xaa;
  273.     color.blue = 0xae;
  274.     color.alpha = 0;
  275.     pixmap = WMCreateBlendedPixmapFromFile(WMWidgetScreen(panel->win),
  276.                        file, &color);
  277.     if (!pixmap) {
  278.     WMSetButtonEnabled(panel->okButton, False);
  279.         
  280.     WMSetLabelText(panel->iconView, _("Could not load image file "));
  281.     
  282.     WMSetLabelImage(panel->iconView, NULL);
  283.     } else {
  284.     WMSetButtonEnabled(panel->okButton, True);
  285.  
  286.     WMSetLabelText(panel->iconView, NULL);
  287.     WMSetLabelImage(panel->iconView, pixmap);
  288.     WMReleasePixmap(pixmap);
  289.     }
  290. }
  291.  
  292.  
  293. static void
  294. listCallback(void *self, void *data)
  295. {
  296.     WMList *lPtr = (WMList*)self;
  297.     IconPanel *panel = (IconPanel*)data;
  298.     char *path;
  299.  
  300.     if (lPtr==panel->dirList) {
  301.     path = WMGetListSelectedItem(lPtr)->text;
  302.     
  303.     WMSetTextFieldText(panel->fileField, path);
  304.  
  305.     WMSetLabelImage(panel->iconView, NULL);
  306.  
  307.     WMSetButtonEnabled(panel->okButton, False);
  308.  
  309.     WMClearList(panel->iconList);
  310.     listPixmaps(panel->scr, panel->iconList, path);    
  311.     } else {
  312.     char *tmp, *iconFile;
  313.     
  314.     path = WMGetListSelectedItem(panel->dirList)->text;
  315.     tmp = wexpandpath(path);
  316.  
  317.     iconFile = WMGetListSelectedItem(panel->iconList)->text;
  318.  
  319.     path = wmalloc(strlen(tmp)+strlen(iconFile)+4);
  320.     strcpy(path, tmp);
  321.     strcat(path, "/");
  322.     strcat(path, iconFile);
  323.     free(tmp);
  324.     WMSetTextFieldText(panel->fileField, path);
  325.     setViewedImage(panel, path);
  326.     free(path);
  327.     }
  328. }
  329.  
  330.  
  331. static void
  332. listIconPaths(WMList *lPtr)
  333. {
  334.     char *paths;
  335.     char *path;
  336.  
  337.     paths = wstrdup(wPreferences.icon_path);
  338.  
  339.     path = strtok(paths, ":");
  340.  
  341.     do {
  342.     char *tmp;
  343.  
  344.     tmp = wexpandpath(path);
  345.     /* do not sort, because the order implies the order of
  346.      * directories searched */
  347.     if (access(tmp, X_OK)==0)
  348.         WMAddListItem(lPtr, path);
  349.     free(tmp);
  350.     } while ((path=strtok(NULL, ":"))!=NULL);
  351.  
  352.     free(paths);
  353. }
  354.  
  355.  
  356. void
  357. drawIconProc(WMList *lPtr, int index, Drawable d, char *text,
  358.          int state, WMRect *rect) 
  359. {
  360.     IconPanel *panel = WMGetHangedData(lPtr);
  361.     GC gc = panel->scr->draw_gc;
  362.     GC copygc = panel->scr->copy_gc;
  363.     char *buffer, *dirfile;
  364.     WMPixmap *pixmap;
  365.     WMColor *blackcolor;
  366.     WMColor *whitecolor;
  367.     WMSize size;
  368.     WMScreen *wmscr=WMWidgetScreen(panel->win);
  369.     int width;
  370.  
  371.     if(!panel->preview) return;
  372.  
  373.     width = rect->size.width;
  374.  
  375.     blackcolor = WMBlackColor(wmscr);
  376.     whitecolor = WMWhiteColor(wmscr);
  377.  
  378.     dirfile = wexpandpath(WMGetListSelectedItem(panel->dirList)->text);
  379.     buffer = wmalloc(strlen(dirfile)+strlen(text)+4);
  380.     sprintf(buffer, "%s/%s", dirfile, text);
  381.     free(dirfile);
  382.  
  383.     pixmap = WMCreatePixmapFromFile(WMWidgetScreen(panel->win), buffer);
  384.     free(buffer);
  385.     if (!pixmap) {
  386.         WMRemoveListItem(lPtr, index);
  387.         return;
  388.     }
  389.  
  390.     XClearArea(dpy, d, rect->pos.x, rect->pos.y, width, rect->size.height, 
  391.            False);
  392.     XSetClipMask(dpy, gc, None);
  393.     /*
  394.     XDrawRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x + 5, 
  395.            rect->pos.y +5, width - 10, 54);
  396.      */
  397.     XDrawLine(dpy, d, WMColorGC(whitecolor), rect->pos.x,
  398.           rect->pos.y+rect->size.height-1, rect->pos.x+width, 
  399.           rect->pos.y+rect->size.height-1);
  400.    
  401.     
  402.     if (state&WLDSSelected) {
  403.         XFillRectangle(dpy, d, WMColorGC(whitecolor), rect->pos.x,
  404.                rect->pos.y, width, rect->size.height);
  405.     }
  406.  
  407.     size = WMGetPixmapSize(pixmap);
  408.  
  409.     XSetClipMask(dpy, copygc, WMGetPixmapMaskXID(pixmap));
  410.     XSetClipOrigin(dpy, copygc, rect->pos.x + (width-size.width)/2,
  411.            rect->pos.y+2);
  412.     XCopyArea(dpy, WMGetPixmapXID(pixmap), d, copygc, 0, 0,
  413.           size.width>100?100:size.width, size.height>64?64:size.height, 
  414.           rect->pos.x + (width-size.width)/2, rect->pos.y+2);
  415.  
  416.     {
  417.         int i,j;
  418.     int fheight = WMFontHeight(panel->normalfont);
  419.     int tlen = strlen(text);
  420.     int twidth = WMWidthOfString(panel->normalfont, text, tlen);
  421.     int ofx, ofy;
  422.     
  423.     ofx = rect->pos.x + (width - twidth)/2;
  424.     ofy = rect->pos.y + 64 - fheight;
  425.     
  426.         for(i=-1;i<2;i++)
  427.         for(j=-1;j<2;j++)
  428.         WMDrawString(wmscr, d, WMColorGC(whitecolor), 
  429.                  panel->normalfont, ofx+i, ofy+j,
  430.                  text, tlen);
  431.  
  432.     WMDrawString(wmscr, d, WMColorGC(blackcolor), panel->normalfont, 
  433.              ofx, ofy, text, tlen);
  434.     }
  435.  
  436.     WMReleasePixmap(pixmap);
  437.     /* I hope it is better to do not use cache / on my box it is fast nuff */
  438.     XFlush(dpy);
  439.  
  440.     WMReleaseColor(blackcolor);
  441.     WMReleaseColor(whitecolor);
  442. }
  443.  
  444.  
  445. static void
  446. buttonCallback(void *self, void *clientData)
  447. {
  448.     WMButton *bPtr = (WMButton*)self;
  449.     IconPanel *panel = (IconPanel*)clientData;
  450.     
  451.     
  452.     if (bPtr==panel->okButton) {
  453.     panel->done = True;
  454.     panel->result = True;
  455.     } else if (bPtr==panel->cancelButton) {
  456.     panel->done = True;
  457.     panel->result = False;
  458.     } else if (bPtr==panel->previewButton) {
  459.         /**** Previewer ****/
  460.         WMSetButtonEnabled(bPtr, False);
  461.         WMSetListUserDrawItemHeight(panel->iconList, 68);
  462.         WMSetListUserDrawProc(panel->iconList, drawIconProc);
  463.         WMRedisplayWidget(panel->iconList);
  464.         /* for draw proc to access screen/gc */
  465.         /*** end preview ***/
  466.     }
  467. #if 0
  468.     else if (bPtr==panel->chooseButton) {
  469.     WMOpenPanel *op;
  470.     
  471.     op = WMCreateOpenPanel(WMWidgetScreen(bPtr));
  472.     
  473.     if (WMRunModalFilePanelForDirectory(op, NULL, "/usr/local", NULL, NULL)) {
  474.         char *path;
  475.         path = WMGetFilePanelFile(op);
  476.         WMSetTextFieldText(panel->fileField, path);
  477.         setViewedImage(panel, path);
  478.         free(path);
  479.     }
  480.     WMDestroyFilePanel(op);
  481.     }
  482. #endif
  483. }
  484.  
  485.  
  486. Bool
  487. wIconChooserDialog(WScreen *scr, char **file, char *instance, char *class)
  488. {
  489.     WWindow *wwin;
  490.     Window parent;
  491.     IconPanel *panel;
  492.     WMColor *color;
  493.     WMFont *boldFont;
  494.     
  495.     panel = wmalloc(sizeof(IconPanel));
  496.     memset(panel, 0, sizeof(IconPanel));
  497.  
  498.     panel->scr = scr;
  499.     
  500.     panel->win = WMCreateWindow(scr->wmscreen, "iconChooser");
  501.     WMResizeWidget(panel->win, 450, 280);
  502.     
  503.     boldFont = WMBoldSystemFontOfSize(scr->wmscreen, 12);
  504.     panel->normalfont = WMSystemFontOfSize(WMWidgetScreen(panel->win), 12);
  505.     
  506.     panel->dirLabel = WMCreateLabel(panel->win);
  507.     WMResizeWidget(panel->dirLabel, 200, 20);
  508.     WMMoveWidget(panel->dirLabel, 10, 7);
  509.     WMSetLabelText(panel->dirLabel, _("Directories"));
  510.     WMSetLabelFont(panel->dirLabel, boldFont);
  511.     WMSetLabelTextAlignment(panel->dirLabel, WACenter);
  512.         
  513.     WMSetLabelRelief(panel->dirLabel, WRSunken);
  514.  
  515.     panel->iconLabel = WMCreateLabel(panel->win);
  516.     WMResizeWidget(panel->iconLabel, 140, 20);
  517.     WMMoveWidget(panel->iconLabel, 215, 7);
  518.     WMSetLabelText(panel->iconLabel, _("Icons"));
  519.     WMSetLabelFont(panel->iconLabel, boldFont);
  520.     WMSetLabelTextAlignment(panel->iconLabel, WACenter);
  521.  
  522.     WMReleaseFont(boldFont);
  523.     
  524.     color = WMWhiteColor(scr->wmscreen);
  525.     WMSetLabelTextColor(panel->dirLabel, color); 
  526.     WMSetLabelTextColor(panel->iconLabel, color);
  527.     WMReleaseColor(color);
  528.  
  529.     color = WMDarkGrayColor(scr->wmscreen);
  530.     WMSetWidgetBackgroundColor(panel->iconLabel, color);
  531.     WMSetWidgetBackgroundColor(panel->dirLabel, color); 
  532.     WMReleaseColor(color);
  533.  
  534.     WMSetLabelRelief(panel->iconLabel, WRSunken);
  535.  
  536.     panel->dirList = WMCreateList(panel->win);
  537.     WMResizeWidget(panel->dirList, 200, 170);
  538.     WMMoveWidget(panel->dirList, 10, 30);
  539.     WMSetListAction(panel->dirList, listCallback, panel);
  540.     
  541.     panel->iconList = WMCreateList(panel->win);
  542.     WMResizeWidget(panel->iconList, 140, 170);
  543.     WMMoveWidget(panel->iconList, 215, 30); 
  544.     WMSetListAction(panel->iconList, listCallback, panel);
  545.  
  546.     WMHangData(panel->iconList,panel);
  547.  
  548.     panel->previewButton = WMCreateCommandButton(panel->win);
  549.     WMResizeWidget(panel->previewButton, 75, 26);
  550.     WMMoveWidget(panel->previewButton, 365, 130);
  551.     WMSetButtonText(panel->previewButton, _("Preview"));
  552.     WMSetButtonAction(panel->previewButton, buttonCallback, panel);
  553.  
  554.     panel->iconView = WMCreateLabel(panel->win);
  555.     WMResizeWidget(panel->iconView, 75, 75);
  556.     WMMoveWidget(panel->iconView, 365, 40);
  557.     WMSetLabelImagePosition(panel->iconView, WIPOverlaps);
  558.     WMSetLabelRelief(panel->iconView, WRSunken);
  559.     WMSetLabelTextAlignment(panel->iconView, WACenter);
  560.  
  561.     panel->fileLabel = WMCreateLabel(panel->win);
  562.     WMResizeWidget(panel->fileLabel, 80, 20);
  563.     WMMoveWidget(panel->fileLabel, 10, 210);
  564.     WMSetLabelText(panel->fileLabel, _("File Name:"));
  565.     
  566.     panel->fileField = WMCreateTextField(panel->win);
  567.     WMResizeWidget(panel->fileField, 345, 20);
  568.     WMMoveWidget(panel->fileField, 95, 210);
  569.     WMSetTextFieldEditable(panel->fileField, False);
  570.     
  571.     panel->okButton = WMCreateCommandButton(panel->win);
  572.     WMResizeWidget(panel->okButton, 80, 26);
  573.     WMMoveWidget(panel->okButton, 360, 240);
  574.     WMSetButtonText(panel->okButton, _("OK"));
  575.     WMSetButtonEnabled(panel->okButton, False);
  576.     WMSetButtonAction(panel->okButton, buttonCallback, panel);
  577.     
  578.     panel->cancelButton = WMCreateCommandButton(panel->win);
  579.     WMResizeWidget(panel->cancelButton, 80, 26);
  580.     WMMoveWidget(panel->cancelButton, 270, 240);
  581.     WMSetButtonText(panel->cancelButton, _("Cancel"));
  582.     WMSetButtonAction(panel->cancelButton, buttonCallback, panel);
  583. #if 0
  584.     panel->chooseButton = WMCreateCommandButton(panel->win);
  585.     WMResizeWidget(panel->chooseButton, 110, 26);
  586.     WMMoveWidget(panel->chooseButton, 150, 240);
  587.     WMSetButtonText(panel->chooseButton, _("Choose File"));
  588.     WMSetButtonAction(panel->chooseButton, buttonCallback, panel);
  589. #endif
  590.     WMRealizeWidget(panel->win);
  591.     WMMapSubwidgets(panel->win);
  592.  
  593.     parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 450, 280, 0, 0, 0);
  594.  
  595.     XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
  596.  
  597.     {
  598.     char *tmp;
  599.  
  600.     tmp = wmalloc((instance ? strlen(instance) : 0)
  601.              + (class ? strlen(class) : 0) + 32);
  602.  
  603.     if (tmp && (instance || class))
  604.         sprintf(tmp, "%s [%s.%s]", _("Icon Chooser"), instance, class);
  605.     else
  606.         strcpy(tmp, _("Icon Chooser"));
  607.  
  608.     wwin = wManageInternalWindow(scr, parent, None, tmp,
  609.                      (scr->scr_width - 450)/2,
  610.                      (scr->scr_height - 280)/2, 450, 280);
  611.     free(tmp);
  612.     }
  613.     
  614.     /* put icon paths in the list */
  615.     listIconPaths(panel->dirList);
  616.     
  617.     WMMapWidget(panel->win);
  618.     
  619.     wWindowMap(wwin);
  620.  
  621.     while (!panel->done) {
  622.     XEvent event;
  623.     
  624.     WMNextEvent(dpy, &event);
  625.     WMHandleEvent(&event);
  626.     }
  627.     
  628.     if (panel->result) {
  629.     char *defaultPath, *wantedPath;
  630.  
  631.     /* check if the file the user selected is not the one that
  632.      * would be loaded by default with the current search path */
  633.     *file = WMGetListSelectedItem(panel->iconList)->text;
  634.     if ((*file)[0]==0) {
  635.         free(*file);
  636.         *file = NULL;
  637.     } else {
  638.         defaultPath = FindImage(wPreferences.icon_path, *file);
  639.         wantedPath = WMGetTextFieldText(panel->fileField);
  640.         /* if the file is not the default, use full path */
  641.         if (strcmp(wantedPath, defaultPath)!=0) {
  642.         *file = wantedPath;
  643.         } else {
  644.         *file = wstrdup(*file);
  645.         free(wantedPath);
  646.         }
  647.         free(defaultPath);
  648.     }
  649.     } else {
  650.     *file = NULL;
  651.     }
  652.  
  653.     WMReleaseFont(panel->normalfont);
  654.  
  655.     WMUnmapWidget(panel->win);
  656.  
  657.     WMDestroyWidget(panel->win);    
  658.  
  659.     wUnmanageWindow(wwin, False, False);
  660.  
  661.     free(panel);
  662.  
  663.     XDestroyWindow(dpy, parent);
  664.     
  665.     return panel->result;
  666. }
  667.  
  668.  
  669. /*
  670.  ***********************************************************************
  671.  * Info Panel
  672.  ***********************************************************************
  673.  */
  674.  
  675.  
  676. typedef struct {
  677.     WScreen *scr;
  678.  
  679.     WWindow *wwin;
  680.  
  681.     WMWindow *win;
  682.  
  683.     WMLabel *logoL;
  684.     WMLabel *name1L;
  685.     WMLabel *name2L;
  686.  
  687.     WMLabel *versionL;
  688.  
  689.     WMLabel *infoL;
  690.  
  691.     WMLabel *copyrL;
  692.  
  693. #ifdef SILLYNESS
  694.     WMHandlerID timer;
  695.     int cycle;
  696.     RImage *icon;
  697.     RImage *pic;
  698.     WMPixmap *oldPix;
  699.     char *str;
  700.     int x;
  701. #endif
  702. } InfoPanel;
  703.  
  704.  
  705.  
  706. #define COPYRIGHT_TEXT  \
  707.      "Copyright \xa9 1997~2000 Alfredo K. Kojima <kojima@windowmaker.org>\n"\
  708.      "Copyright \xa9 1998~2000 Dan Pascu <dan@windowmaker.org>"
  709.  
  710.  
  711.  
  712. static InfoPanel *thePanel = NULL;
  713.  
  714. static void
  715. destroyInfoPanel(WCoreWindow *foo, void *data, XEvent *event)
  716. {
  717. #ifdef SILLYNESS
  718.     if (thePanel->timer) {
  719.     WMDeleteTimerHandler(thePanel->timer);
  720.     }
  721.     if (thePanel->oldPix) {
  722.     WMReleasePixmap(thePanel->oldPix);
  723.     }
  724.     if (thePanel->icon) {
  725.     RDestroyImage(thePanel->icon);
  726.     }
  727.     if (thePanel->pic) {
  728.     RDestroyImage(thePanel->pic);
  729.     }
  730. #endif /* SILLYNESS */
  731.     WMUnmapWidget(thePanel);
  732.  
  733.     wUnmanageWindow(thePanel->wwin, False, False);
  734.  
  735.     WMDestroyWidget(thePanel->win);
  736.  
  737.     free(thePanel);
  738.     
  739.     thePanel = NULL;
  740. }
  741.  
  742.  
  743. WMPixmap*
  744. renderText(WMScreen *scr, char *text, char *font, RColor *from, RColor *to)
  745. {
  746.     WMPixmap *wpix = NULL;
  747.     Pixmap grad = None;
  748.     Pixmap mask = None;
  749.     RContext *rc = WMScreenRContext(scr);
  750.     XFontStruct *f = NULL;
  751.     int w, h;
  752.     GC gc = None;
  753.     
  754.     f = XLoadQueryFont(dpy, font);
  755.     if (!f)
  756.     return NULL;
  757.  
  758.     w = XTextWidth(f, text, strlen(text));
  759.     h = f->ascent+f->descent;
  760.  
  761.     mask = XCreatePixmap(dpy, rc->drawable, w, h, 1);
  762.     gc = XCreateGC(dpy, mask, 0, NULL);
  763.     XSetForeground(dpy, gc, 0);
  764.     XSetFont(dpy, gc, f->fid);
  765.     XFillRectangle(dpy, mask, gc, 0, 0, w, h);
  766.  
  767.     XSetForeground(dpy, gc, 1);
  768.     XDrawString(dpy, mask, gc, 0, f->ascent, text, strlen(text));
  769.     XSetLineAttributes(dpy, gc, 3, LineSolid, CapRound, JoinMiter);
  770.     XDrawLine(dpy, mask, gc, 0, h-2, w, h-2);
  771.  
  772.     grad = XCreatePixmap(dpy, rc->drawable, w, h, rc->depth);
  773.     {
  774.     WMColor *color;
  775.  
  776.     color = WMBlackColor(scr);
  777.     XFillRectangle(dpy, grad, WMColorGC(color), 0, 0, w, h);
  778.     WMReleaseColor(color);
  779.     }
  780.  
  781.     wpix = WMCreatePixmapFromXPixmaps(scr, grad, mask, w, h, rc->depth);
  782.  
  783.     if (gc)
  784.     XFreeGC(dpy, gc);
  785.     XFreeFont(dpy, f);
  786.  
  787.     return wpix;
  788. }
  789.  
  790. #ifdef SILLYNESS
  791.  
  792. extern WMPixmap *DoXThing();
  793. extern Bool InitXThing();
  794.  
  795. static void
  796. logoPushCallback(void *data)
  797. {
  798.     InfoPanel *panel = (InfoPanel*)data;
  799.     char buffer[512];
  800.     int i;
  801.     int len;
  802.     static int jingobeu[] = {
  803.     329, 150, -1, 100, 329, 150, -1, 100, 329, 300, -1, 250,
  804.         329, 150, -1, 100, 329, 150, -1, 100,  329, 300, -1, 250,
  805.         329, 150, 392, 150, 261, 150, 293, 150, 329, 400, -1, 400, 0
  806.     };
  807.     static int c = 0;
  808.  
  809.     if (panel->x) {
  810.     XKeyboardControl kc;
  811.     
  812.     if (panel->x > 0) {
  813.         if(jingobeu[panel->x-1]==0){panel->x=-1;}else if(jingobeu[panel->x
  814. -1]<0){panel->x++;c=jingobeu[panel->x-1]/50;panel->x++;}else if(c==0){
  815.     kc.bell_pitch=jingobeu[panel->x-1];panel->x++;kc.bell_percent=50;c=
  816.     jingobeu[panel->x-1]/50;kc.bell_duration=jingobeu[panel->x-1];panel->x++;
  817. XChangeKeyboardControl(dpy,KBBellPitch|KBBellDuration|KBBellPercent,&kc);
  818.     XBell(dpy,50);XFlush(dpy);}else{c--;}}
  819.     if (!(panel->cycle % 4)) {
  820.         WMPixmap *p;
  821.  
  822.         p = DoXThing(panel->wwin);
  823.         WMSetLabelImage(panel->logoL, p);
  824.     }
  825.     } else if (panel->cycle < 30) {
  826.     RImage *image;
  827.     WMPixmap *pix;
  828.  
  829.     image = RCloneImage(panel->icon);
  830.     RCombineImagesWithOpaqueness(image, panel->pic, panel->cycle*255/30);
  831.     pix = WMCreatePixmapFromRImage(panel->scr->wmscreen, image, 128);
  832.     RDestroyImage(image);
  833.     WMSetLabelImage(panel->logoL, pix);
  834.     WMReleasePixmap(pix);
  835.     }
  836.  
  837.     i = panel->cycle%200;
  838.  
  839.     len = strlen(panel->str);
  840.  
  841.     strncpy(buffer, panel->str, i<len ? i : len);
  842.     if (i >= len)
  843.     memset(&buffer[len], ' ', i-len);
  844.  
  845.     strncpy(buffer, panel->str, i<len ? i : len);
  846.     if (i >= len)
  847.     memset(&buffer[len], ' ', i-len);
  848.     buffer[i]=0;
  849.     WMSetLabelText(panel->versionL, buffer);
  850.  
  851.     panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
  852.     panel->cycle++;
  853. }
  854.  
  855.  
  856. static void
  857. handleLogoPush(XEvent *event, void *data)
  858. {
  859.     InfoPanel *panel = (InfoPanel*)data;
  860.     static int broken = 0;
  861.     static int clicks = 0;
  862.     static char *pic_data[] = {
  863. "45 45 57 1",
  864. "     c None",
  865. ".    c #000000",
  866. "X    c #383C00",
  867. "o    c #515500",
  868. "O    c #616100",
  869. "+    c #616900",
  870. "@    c #696D00",
  871. "#    c #697100",
  872. "$    c #495100",
  873. "%    c #202800",
  874. "&    c #969600",
  875. "*    c #CFCF00",
  876. "=    c #D7DB00",
  877. "-    c #D7D700",
  878. ";    c #C7CB00",
  879. ":    c #A6AA00",
  880. ">    c #494900",
  881. ",    c #8E8E00",
  882. "<    c #DFE700",
  883. "1    c #F7FF00",
  884. "2    c #FFFF00",
  885. "3    c #E7EB00",
  886. "4    c #B6B600",
  887. "5    c #595900",
  888. "6    c #717500",
  889. "7    c #AEB200",
  890. "8    c #CFD300",
  891. "9    c #E7EF00",
  892. "0    c #EFF300",
  893. "q    c #9EA200",
  894. "w    c #F7FB00",
  895. "e    c #F7F700",
  896. "r    c #BEBE00",
  897. "t    c #8E9200",
  898. "y    c #EFF700",
  899. "u    c #969A00",
  900. "i    c #414500",
  901. "p    c #595D00",
  902. "a    c #E7E700",
  903. "s    c #C7C700",
  904. "d    c #797D00",
  905. "f    c #BEC300",
  906. "g    c #DFE300",
  907. "h    c #868600",
  908. "j    c #EFEF00",
  909. "k    c #9E9E00",
  910. "l    c #616500",
  911. "z    c #DFDF00",
  912. "x    c #868A00",
  913. "c    c #969200",
  914. "v    c #B6BA00",
  915. "b    c #A6A600",
  916. "n    c #8E8A00",
  917. "m    c #717100",
  918. "M    c #AEAE00",
  919. "N    c #AEAA00",
  920. "B    c #868200",
  921. "               ...............               ",
  922. "             ....XoO+@##+O$%....             ",
  923. "           ...%X&*========-;;:o...           ",
  924. "         ...>.>,<122222222222134@...         ",
  925. "        ..>5678912222222222222220q%..        ",
  926. "       ..$.&-w2222222222222222222er>..       ",
  927. "      ..O.t31222222222222222222222y4>..      ",
  928. "    ...O5u3222222222222222222222222yri...    ",
  929. "    ..>p&a22222222222222222222222222wso..    ",
  930. "   ..ids91222222222222222222222222222wfi..   ",
  931. "  ..X.7w222222wgs-w2222222213=g0222222<hi..  ",
  932. "  ..Xuj2222222<@X5=222222229k@l:022222y4i..  ",
  933. "  .Xdz22222222*X%.s22222222axo%$-222222<c>.. ",
  934. " ..o7y22222222v...r222222223hX.i82222221si.. ",
  935. "..io*222222222&...u22222222yt..%*22222220:%. ",
  936. "..>k02222222227...f222222222v..X=222222229t. ",
  937. "..dz12222222220ui:y2222222223d%qw222222221g. ",
  938. ".%vw222222222221y2222222222219*y2222222222wd.",
  939. ".X;2222222222222222222222222222222222222222b.",
  940. ".i*2222222222222222222222222222222222222222v.",
  941. ".i*2222222222222222222222222222222222222222;.",
  942. ".i*22222222222222222222222222222222222222228.",
  943. ".>*2222222222222222222222222222222222222222=.",
  944. ".i*22222222222222222222222222222222222222228.",
  945. ".i*2222222222222222222222222222222222222222;.",
  946. ".X*222222222222222222222222222222we12222222r.",
  947. ".Xs12222222w3aw22222222222222222y8s0222222wk.",
  948. ".Xq02222222a,na22222222222222222zm6zwy2222gi.",
  949. "..>*22222y<:Xcj22222222222222222-o$k;;02228..",
  950. "..i7y2220rhX.:y22222222222222222jtiXd,a220,..",
  951. " .X@z222a,do%kj2222222222222222wMX5q;gw228%..",
  952. " ..58222wagsh6ry222222222222221;>Of0w222y:...",
  953. " ...:e2222218mdz22222222222222a&$vw222220@...",
  954. " ...O-122222y:.u02222222222229q$uj222221r... ",
  955. "  ..%&a1222223&573w2222222219NOxz122221z>... ",
  956. "   ...t3222221-l$nr8ay1222yzbo,=12222w-5...  ",
  957. "    ..X:022222w-k+>o,7s**s7xOn=12221<f5...   ",
  958. "     ..o:9222221j8:&Bl>>>>ihv<12221=dX...    ",
  959. "      ..Xb9122222109g-****;<y22221zn%...     ",
  960. "       ..X&801222222222222222222w-h....      ",
  961. "        ...o:=022222222222222221=lX...       ",
  962. "          ..X@:;3w2222222222210fO...         ",
  963. "           ...XX&v8<30000003-N@...           ",
  964. "             .....XmnbN:q&Bo....             ",
  965. "                 ............                "};
  966.     static char *msgs[] = {
  967.         "Have a nice day!"
  968.     };
  969.  
  970.  
  971.     clicks++;
  972.     if (!panel->timer && !broken && clicks > 0) {
  973.     char *file;
  974.     char *path;
  975.  
  976.     panel->x = 0;
  977.     clicks = 0;
  978.     if (!panel->icon) {
  979.         file = wDefaultGetIconFile(panel->scr, "Logo", "WMPanel", False);
  980.         if (!file) {
  981.         broken = 1;
  982.         return;
  983.         }
  984.     
  985.         path = FindImage(wPreferences.icon_path, file);
  986.         if (!path) {
  987.         broken = 1;
  988.         return;
  989.         }
  990.  
  991.         panel->icon = RLoadImage(panel->scr->rcontext, path, 0);
  992.         free(path);
  993.         if (!panel->icon) {
  994.         broken = 1;
  995.         return;
  996.         }
  997.     }
  998.     if (!panel->pic) {
  999.         panel->pic = RGetImageFromXPMData(panel->scr->rcontext, pic_data);
  1000.         if (!panel->pic || panel->icon->width!=panel->pic->width
  1001.         || panel->icon->height!=panel->pic->height) {
  1002.         broken = 1;
  1003.         RDestroyImage(panel->icon);
  1004.         panel->icon = NULL;
  1005.         if (panel->pic) {
  1006.             RDestroyImage(panel->pic);
  1007.             panel->pic = NULL;
  1008.         }
  1009.         return;
  1010.         }
  1011.  
  1012.         {
  1013.         RColor color;
  1014.         color.red = 0xae;
  1015.         color.green = 0xaa;
  1016.         color.blue = 0xae;
  1017.         color.alpha = 255;
  1018.         RCombineImageWithColor(panel->icon, &color);
  1019.         RCombineImageWithColor(panel->pic, &color);
  1020.         }
  1021.     }
  1022.  
  1023.     panel->str = msgs[rand()%(sizeof(msgs)/sizeof(char*))];
  1024.  
  1025.     panel->timer = WMAddTimerHandler(50, logoPushCallback, panel);
  1026.     panel->cycle = 0;
  1027.     panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
  1028.     } else if (panel->timer) {
  1029.     char version[20];
  1030.  
  1031.     panel->x = 0;
  1032.     clicks = 0;
  1033.     WMSetLabelImage(panel->logoL, panel->oldPix);
  1034.     WMReleasePixmap(panel->oldPix);
  1035.     panel->oldPix = NULL;
  1036.     
  1037.     WMDeleteTimerHandler(panel->timer);
  1038.     panel->timer = NULL;
  1039.  
  1040.     sprintf(version, "Version %s", VERSION);
  1041.     WMSetLabelText(panel->versionL, version);
  1042.     }
  1043.  
  1044.     {
  1045.     XEvent ev;
  1046.     while (XCheckTypedWindowEvent(dpy, WMWidgetXID(panel->versionL),
  1047.                       ButtonPress, &ev));
  1048.     }
  1049. }
  1050. #endif /* SILLYNESS */
  1051.  
  1052.  
  1053. void
  1054. wShowInfoPanel(WScreen *scr)
  1055. {
  1056.     InfoPanel *panel;
  1057.     WMPixmap *logo;
  1058.     WMSize size;
  1059.     WMFont *font;
  1060.     char version[32];
  1061.     char buffer[512];
  1062.     Window parent;
  1063.     WWindow *wwin;
  1064.     RColor color1, color2;
  1065.     char **strl;
  1066.     int i;
  1067.     char *visuals[] = {
  1068.     "StaticGray",
  1069.         "GrayScale",
  1070.         "StaticColor",
  1071.         "PseudoColor",
  1072.         "TrueColor",
  1073.         "DirectColor"
  1074.     };
  1075.  
  1076.  
  1077.     if (thePanel) {
  1078.     if (thePanel->scr == scr) {
  1079.         wRaiseFrame(thePanel->wwin->frame->core);
  1080.         wSetFocusTo(scr, thePanel->wwin);
  1081.     }
  1082.     return;
  1083.     }
  1084.     
  1085.     panel = wmalloc(sizeof(InfoPanel));
  1086.     memset(panel, 0, sizeof(InfoPanel));
  1087.  
  1088.     panel->scr = scr;
  1089.  
  1090.     panel->win = WMCreateWindow(scr->wmscreen, "info");
  1091.     WMResizeWidget(panel->win, 382, 230);
  1092.     
  1093.     logo = WMGetApplicationIconImage(scr->wmscreen);
  1094.     if (logo) {
  1095.     size = WMGetPixmapSize(logo);
  1096.     panel->logoL = WMCreateLabel(panel->win);
  1097.     WMResizeWidget(panel->logoL, 64, 64);
  1098.     WMMoveWidget(panel->logoL, 30, 20);
  1099.     WMSetLabelImagePosition(panel->logoL, WIPImageOnly);
  1100.     WMSetLabelImage(panel->logoL, logo);
  1101. #ifdef SILLYNESS
  1102.     WMCreateEventHandler(WMWidgetView(panel->logoL), ButtonPressMask,
  1103.                  handleLogoPush, panel);
  1104. #endif
  1105.     }
  1106.  
  1107.     panel->name1L = WMCreateLabel(panel->win);
  1108.     WMResizeWidget(panel->name1L, 240, 30);
  1109.     WMMoveWidget(panel->name1L, 100, 30);
  1110.     color1.red = 0;
  1111.     color1.green = 0;
  1112.     color1.blue = 0;
  1113.     color2.red = 0x50;
  1114.     color2.green = 0x50;
  1115.     color2.blue = 0x70;
  1116.     logo = renderText(scr->wmscreen, "GNU Window Maker",
  1117.               "-*-utopia-*-r-*-*-25-*", &color1, &color2);
  1118.     if (logo) {
  1119.     WMSetLabelImagePosition(panel->name1L, WIPImageOnly);
  1120.     WMSetLabelImage(panel->name1L, logo);
  1121.     WMReleasePixmap(logo);
  1122.     } else {
  1123.     font = WMBoldSystemFontOfSize(scr->wmscreen, 20);
  1124.     if (font) {
  1125.         WMSetLabelFont(panel->name1L, font);
  1126.         WMReleaseFont(font);
  1127.     }
  1128.     WMSetLabelTextAlignment(panel->name1L, WACenter);
  1129.     WMSetLabelText(panel->name1L, "GNU Window Maker");
  1130.     }
  1131.  
  1132.     panel->name2L = WMCreateLabel(panel->win);
  1133.     WMResizeWidget(panel->name2L, 240, 24);
  1134.     WMMoveWidget(panel->name2L, 100, 60);
  1135.     font = WMBoldSystemFontOfSize(scr->wmscreen, 18);
  1136.     if (font) {
  1137.     WMSetLabelFont(panel->name2L, font);
  1138.     WMReleaseFont(font);
  1139.     font = NULL;
  1140.     }
  1141.     WMSetLabelTextAlignment(panel->name2L, WACenter);
  1142.     WMSetLabelText(panel->name2L, "Window Manager for X");
  1143.  
  1144.     
  1145.     sprintf(version, "Version %s", VERSION);
  1146.     panel->versionL = WMCreateLabel(panel->win);
  1147.     WMResizeWidget(panel->versionL, 310, 16);
  1148.     WMMoveWidget(panel->versionL, 30, 95);
  1149.     WMSetLabelTextAlignment(panel->versionL, WARight);
  1150.     WMSetLabelText(panel->versionL, version);
  1151.     WMSetLabelWraps(panel->versionL, False);
  1152.  
  1153.     panel->copyrL = WMCreateLabel(panel->win);
  1154.     WMResizeWidget(panel->copyrL, 340, 40);
  1155.     WMMoveWidget(panel->copyrL, 15, 185);
  1156.     WMSetLabelTextAlignment(panel->copyrL, WALeft);
  1157.     WMSetLabelText(panel->copyrL, COPYRIGHT_TEXT);
  1158.     /* we want the (c) character in the helvetica font */
  1159.     font = WMCreateNormalFont(scr->wmscreen, HELVETICA10_FONT);
  1160.     if (font) {
  1161.     WMSetLabelFont(panel->copyrL, font);
  1162.     }
  1163.  
  1164.     switch (scr->w_depth) {
  1165.      case 15:
  1166.     strcpy(version, "32 thousand");
  1167.     break;
  1168.      case 16:
  1169.     strcpy(version, "64 thousand");
  1170.     break;
  1171.      case 24:
  1172.      case 32:
  1173.     strcpy(version, "16 million");
  1174.     break;
  1175.      default:
  1176.     sprintf(version, "%d", 1<<scr->w_depth);
  1177.     break;
  1178.     }
  1179.  
  1180.     sprintf(buffer, "Using visual 0x%x: %s %ibpp (%s colors)\n",
  1181.         (unsigned)scr->w_visual->visualid,
  1182.         visuals[scr->w_visual->class], scr->w_depth, version);
  1183.  
  1184.     strcat(buffer, "Supported image formats: ");
  1185.     strl = RSupportedFileFormats();
  1186.     for (i=0; strl[i]!=NULL; i++) {
  1187.     strcat(buffer, strl[i]);
  1188.     strcat(buffer, " ");
  1189.     }
  1190.  
  1191.     strcat(buffer, "\nAdditional Support For: ");
  1192.     {
  1193.     char *list[8];
  1194.     char buf[80];
  1195.     int j = 0;
  1196.  
  1197. #ifdef MWM_HINTS
  1198.     list[j++] = "MWM";
  1199. #endif
  1200. #ifdef KWM_HINTS
  1201.     list[j++] = "KDE";
  1202. #endif
  1203. #ifdef GNOME_STUFF
  1204.     list[j++] = "GNOME";
  1205. #endif
  1206. #ifdef OLWM_HINTS
  1207.     list[j++] = "OLWM";
  1208. #endif
  1209. #ifdef WMSOUND
  1210.     list[j++] = "Sound";
  1211. #endif
  1212.  
  1213.     buf[0] = 0;
  1214.     for (i = 0; i < j; i++) {
  1215.         if (i > 0) {
  1216.         if (i == j - 1)
  1217.             strcat(buf, " and ");
  1218.         else
  1219.             strcat(buf, ", ");
  1220.         }
  1221.         strcat(buf, list[i]);
  1222.     }
  1223.     strcat(buffer, buf);
  1224.     }
  1225.  
  1226.  
  1227.     panel->infoL = WMCreateLabel(panel->win);
  1228.     WMResizeWidget(panel->infoL, 350, 75);
  1229.     WMMoveWidget(panel->infoL, 15, 115);
  1230.     WMSetLabelText(panel->infoL, buffer);
  1231.     if (font) {
  1232.     WMSetLabelFont(panel->infoL, font);
  1233.     WMReleaseFont(font);
  1234.     }
  1235.  
  1236.     
  1237.     WMRealizeWidget(panel->win);
  1238.     WMMapSubwidgets(panel->win);
  1239.  
  1240.     parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 382, 230, 0, 0, 0);
  1241.  
  1242.     XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
  1243.  
  1244.     WMMapWidget(panel->win);
  1245.  
  1246.     wwin = wManageInternalWindow(scr, parent, None, "Info",
  1247.                  (scr->scr_width - 382)/2,
  1248.                  (scr->scr_height - 230)/2, 382, 230);
  1249.  
  1250.     WSETUFLAG(wwin, no_closable, 0);
  1251.     WSETUFLAG(wwin, no_close_button, 0);
  1252. #ifdef XKB_BUTTON_HINT
  1253.     wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
  1254. #endif
  1255.     wWindowUpdateButtonImages(wwin);
  1256.     wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
  1257.     wwin->frame->on_click_right = destroyInfoPanel;
  1258.     
  1259.     wWindowMap(wwin);
  1260.  
  1261.     panel->wwin = wwin;
  1262.  
  1263.     thePanel = panel;
  1264. #ifdef SILLYNESS
  1265.     if (InitXThing(panel->scr)) {    
  1266.     panel->timer = WMAddTimerHandler(100, logoPushCallback, panel);
  1267.     panel->cycle = 0;
  1268.     panel->x = 1;
  1269.     panel->str = "Merry Christmas!";
  1270.     panel->oldPix = WMRetainPixmap(WMGetLabelImage(panel->logoL));
  1271.     } 
  1272. #endif
  1273. }
  1274.  
  1275.  
  1276. /*
  1277.  ***********************************************************************
  1278.  * Legal Panel
  1279.  ***********************************************************************
  1280.  */
  1281.  
  1282. typedef struct {
  1283.     WScreen *scr;
  1284.     
  1285.     WWindow *wwin;
  1286.  
  1287.     WMWindow *win;
  1288.     
  1289.     WMLabel *licenseL;
  1290. } LegalPanel;
  1291.  
  1292.  
  1293.  
  1294. #define LICENSE_TEXT \
  1295.     "    Window Maker is free software; you can redistribute it and/or modify "\
  1296.     "it under the terms of the GNU General Public License as published "\
  1297.     "by the Free Software Foundation; either version 2 of the License, "\
  1298.     "or (at your option) any later version.\n\n\n"\
  1299.     "    Window Maker is distributed in the hope that it will be useful, but "\
  1300.     "WITHOUT ANY WARRANTY; without even the implied warranty of "\
  1301.     "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU "\
  1302.     "General Public License for more details.\n\n\n"\
  1303.     "    You should have received a copy of the GNU General Public License "\
  1304.     "along with this program; if not, write to the Free Software "\
  1305.     "Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA "\
  1306.     "02111-1307, USA."
  1307.  
  1308.  
  1309. static LegalPanel *legalPanel = NULL;
  1310.  
  1311. static void
  1312. destroyLegalPanel(WCoreWindow *foo, void *data, XEvent *event)
  1313. {
  1314.     WMUnmapWidget(legalPanel->win);
  1315.  
  1316.     WMDestroyWidget(legalPanel->win);    
  1317.  
  1318.     wUnmanageWindow(legalPanel->wwin, False, False);
  1319.  
  1320.     free(legalPanel);
  1321.     
  1322.     legalPanel = NULL;
  1323. }
  1324.  
  1325.  
  1326. void
  1327. wShowLegalPanel(WScreen *scr)
  1328. {
  1329.     LegalPanel *panel;
  1330.     Window parent;
  1331.     WWindow *wwin;
  1332.  
  1333.     if (legalPanel) {
  1334.     if (legalPanel->scr == scr) {
  1335.         wRaiseFrame(legalPanel->wwin->frame->core);
  1336.         wSetFocusTo(scr, legalPanel->wwin);
  1337.     }
  1338.     return;
  1339.     }
  1340.  
  1341.     panel = wmalloc(sizeof(LegalPanel));
  1342.  
  1343.     panel->scr = scr;
  1344.     
  1345.     panel->win = WMCreateWindow(scr->wmscreen, "legal");
  1346.     WMResizeWidget(panel->win, 420, 250);
  1347.  
  1348.     
  1349.     panel->licenseL = WMCreateLabel(panel->win);
  1350.     WMResizeWidget(panel->licenseL, 400, 230);
  1351.     WMMoveWidget(panel->licenseL, 10, 10);
  1352.     WMSetLabelTextAlignment(panel->licenseL, WALeft);
  1353.     WMSetLabelText(panel->licenseL, LICENSE_TEXT);
  1354.     WMSetLabelRelief(panel->licenseL, WRGroove);
  1355.  
  1356.     WMRealizeWidget(panel->win);
  1357.     WMMapSubwidgets(panel->win);
  1358.  
  1359.     parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 420, 250, 0, 0, 0);
  1360.  
  1361.     XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
  1362.  
  1363.     wwin = wManageInternalWindow(scr, parent, None, "Legal",
  1364.                  (scr->scr_width - 420)/2,
  1365.                  (scr->scr_height - 250)/2, 420, 250);
  1366.  
  1367.     WSETUFLAG(wwin, no_closable, 0);
  1368.     WSETUFLAG(wwin, no_close_button, 0);
  1369.     wWindowUpdateButtonImages(wwin);
  1370.     wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
  1371. #ifdef XKB_BUTTON_HINT
  1372.     wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
  1373. #endif
  1374.     wwin->frame->on_click_right = destroyLegalPanel;
  1375.     
  1376.     panel->wwin = wwin;
  1377.     
  1378.     WMMapWidget(panel->win);
  1379.  
  1380.     wWindowMap(wwin);
  1381.  
  1382.     legalPanel = panel;
  1383. }
  1384.  
  1385.  
  1386. /*
  1387.  ***********************************************************************
  1388.  * Crashing Dialog Panel
  1389.  ***********************************************************************
  1390.  */
  1391.  
  1392. extern WDDomain *WDWindowAttributes;
  1393.  
  1394.  
  1395. typedef struct _CrashPanel {
  1396.     WMWindow *win;            /* main window */
  1397.  
  1398.     WMLabel *iconL;           /* application icon */
  1399.     WMLabel *nameL;           /* title of panel */
  1400.  
  1401.     WMFrame *sepF;            /* separator frame */
  1402.  
  1403.     WMLabel *noteL;           /* Title of note */
  1404.     WMLabel *note2L;          /* body of note with what happened */
  1405.  
  1406.     WMFrame *whatF;           /* "what to do next" frame */
  1407.     WMPopUpButton *whatP;     /* action selection popup button */
  1408.  
  1409.     WMButton *okB;            /* ok button */
  1410.  
  1411.     Bool done;                /* if finished with this dialog */
  1412.     int action;               /* what to do after */
  1413.  
  1414.     KeyCode retKey;
  1415.  
  1416. } CrashPanel;
  1417.  
  1418.  
  1419. static void
  1420. handleKeyPress(XEvent *event, void *clientData)
  1421. {
  1422.     CrashPanel *panel = (CrashPanel*)clientData;
  1423.  
  1424.     if (event->xkey.keycode == panel->retKey) {
  1425.     WMPerformButtonClick(panel->okB);
  1426.     }
  1427. }
  1428.  
  1429.  
  1430. static void
  1431. okButtonCallback(void *self, void *clientData)
  1432. {
  1433.     CrashPanel *panel = (CrashPanel*)clientData;
  1434.  
  1435.     panel->done = True;
  1436. }
  1437.  
  1438.  
  1439. static void
  1440. setCrashAction(void *self, void *clientData)
  1441. {
  1442.     WMPopUpButton *pop = (WMPopUpButton*)self;
  1443.     CrashPanel *panel = (CrashPanel*)clientData;
  1444.  
  1445.     panel->action = WMGetPopUpButtonSelectedItem(pop);
  1446. }
  1447.  
  1448.  
  1449. static WMPixmap*
  1450. getWindowMakerIconImage(WMScreen *scr)
  1451. {
  1452.     proplist_t dict, key, option, value=NULL;
  1453.     WMPixmap *pix=NULL;
  1454.     char *path;
  1455.  
  1456.     PLSetStringCmpHook(NULL);
  1457.  
  1458.     key = PLMakeString("Logo.WMPanel");
  1459.     option = PLMakeString("Icon");
  1460.  
  1461.     dict = PLGetDictionaryEntry(WDWindowAttributes->dictionary, key);
  1462.  
  1463.     if (dict) {
  1464.         value = PLGetDictionaryEntry(dict, option);
  1465.     }
  1466.  
  1467.     PLRelease(key);
  1468.     PLRelease(option);
  1469.  
  1470.     PLSetStringCmpHook(StringCompareHook);
  1471.  
  1472.     if (value && PLIsString(value)) {
  1473.         path = FindImage(wPreferences.icon_path, PLGetString(value));
  1474.  
  1475.         if (path) {
  1476.             RImage *image;
  1477.  
  1478.             image = RLoadImage(WMScreenRContext(scr), path, 0);
  1479.             if (image) {
  1480.                 pix = WMCreatePixmapFromRImage(scr, image, 0);
  1481.                 RDestroyImage(image);
  1482.             }
  1483.             free(path);
  1484.         }
  1485.     }
  1486.  
  1487.     return pix;
  1488. }
  1489.  
  1490.  
  1491. #define PWIDTH    295
  1492. #define PHEIGHT    345
  1493.  
  1494.  
  1495. int
  1496. wShowCrashingDialogPanel(int whatSig)
  1497. {
  1498.     CrashPanel *panel;
  1499.     WMScreen *scr;
  1500.     WMFont *font;
  1501.     WMPixmap *logo;
  1502.     int screen_no, scr_width, scr_height;
  1503.     int action;
  1504.     char buf[256];
  1505.  
  1506.     panel = wmalloc(sizeof(CrashPanel));
  1507.     memset(panel, 0, sizeof(CrashPanel));
  1508.  
  1509.     screen_no = DefaultScreen(dpy);
  1510.     scr_width = WidthOfScreen(ScreenOfDisplay(dpy, screen_no));
  1511.     scr_height = HeightOfScreen(ScreenOfDisplay(dpy, screen_no));
  1512.  
  1513.     scr = WMCreateScreen(dpy, screen_no);
  1514.     if (!scr) {
  1515.         wsyserror(_("cannot open connection for crashing dialog panel. Aborting."));
  1516.     return WMAbort;
  1517.     }
  1518.  
  1519.     panel->retKey = XKeysymToKeycode(dpy, XK_Return);
  1520.  
  1521.     panel->win = WMCreateWindow(scr, "crashingDialog");
  1522.     WMResizeWidget(panel->win, PWIDTH, PHEIGHT);
  1523.     WMMoveWidget(panel->win, (scr_width - PWIDTH)/2, (scr_height - PHEIGHT)/2);
  1524.  
  1525.     logo = getWindowMakerIconImage(scr);
  1526.     if (logo) {
  1527.         panel->iconL = WMCreateLabel(panel->win);
  1528.         WMResizeWidget(panel->iconL, 64, 64);
  1529.         WMMoveWidget(panel->iconL, 10, 10);
  1530.         WMSetLabelImagePosition(panel->iconL, WIPImageOnly);
  1531.         WMSetLabelImage(panel->iconL, logo);
  1532.     }
  1533.  
  1534.     panel->nameL = WMCreateLabel(panel->win);
  1535.     WMResizeWidget(panel->nameL, 190, 18);
  1536.     WMMoveWidget(panel->nameL, 80, 35);
  1537.     WMSetLabelTextAlignment(panel->nameL, WALeft);
  1538.     font = WMBoldSystemFontOfSize(scr, 18);
  1539.     WMSetLabelFont(panel->nameL, font);
  1540.     WMReleaseFont(font);
  1541.     WMSetLabelText(panel->nameL, _("Fatal error"));
  1542.  
  1543.     panel->sepF = WMCreateFrame(panel->win);
  1544.     WMResizeWidget(panel->sepF, PWIDTH+4, 2);
  1545.     WMMoveWidget(panel->sepF, -2, 80);
  1546.  
  1547.     panel->noteL = WMCreateLabel(panel->win);
  1548.     WMResizeWidget(panel->noteL, PWIDTH-20, 40);
  1549.     WMMoveWidget(panel->noteL, 10, 90);
  1550.     WMSetLabelTextAlignment(panel->noteL, WAJustified);
  1551. #ifdef SYS_SIGLIST_DECLARED
  1552.     sprintf(buf, _("Window Maker received signal %i\n(%s)."),
  1553.             whatSig, sys_siglist[whatSig]);
  1554. #else
  1555.     sprintf(buf, _("Window Maker received signal %i."), whatSig);
  1556. #endif
  1557.     WMSetLabelText(panel->noteL, buf);
  1558.  
  1559.     panel->note2L = WMCreateLabel(panel->win);
  1560.     WMResizeWidget(panel->note2L, PWIDTH-20, 100);
  1561.     WMMoveWidget(panel->note2L, 10, 130);
  1562.     WMSetLabelTextAlignment(panel->note2L, WALeft);
  1563.     WMSetLabelText(panel->note2L,
  1564.                    _(" This fatal error occured probably due to a bug."
  1565.                    " Please fill the included BUGFORM and "
  1566.                    "report it to bugs@windowmaker.org."));
  1567.  
  1568.  
  1569.     panel->whatF = WMCreateFrame(panel->win);
  1570.     WMResizeWidget(panel->whatF, PWIDTH-20, 50);
  1571.     WMMoveWidget(panel->whatF, 10, 240);
  1572.     WMSetFrameTitle(panel->whatF, _("What do you want to do now?"));
  1573.  
  1574.     panel->whatP = WMCreatePopUpButton(panel->whatF);
  1575.     WMResizeWidget(panel->whatP, PWIDTH-20-70, 20);
  1576.     WMMoveWidget(panel->whatP, 35, 20);
  1577.     WMSetPopUpButtonPullsDown(panel->whatP, False);
  1578.     WMSetPopUpButtonText(panel->whatP, _("Select action"));
  1579.     WMAddPopUpButtonItem(panel->whatP, _("Abort and leave a core file"));
  1580.     WMAddPopUpButtonItem(panel->whatP, _("Restart Window Maker"));
  1581.     WMAddPopUpButtonItem(panel->whatP, _("Start alternate window manager"));
  1582.     WMSetPopUpButtonAction(panel->whatP, setCrashAction, panel);
  1583.     WMSetPopUpButtonSelectedItem(panel->whatP, WMRestart);
  1584.     panel->action = WMRestart;
  1585.  
  1586.     WMMapSubwidgets(panel->whatF);
  1587.  
  1588.     panel->okB = WMCreateCommandButton(panel->win);
  1589.     WMResizeWidget(panel->okB, 80, 26);
  1590.     WMMoveWidget(panel->okB, 205, 309);
  1591.     WMSetButtonText(panel->okB, _("OK"));
  1592.     WMSetButtonImage(panel->okB, WMGetSystemPixmap(scr, WSIReturnArrow));
  1593.     WMSetButtonAltImage(panel->okB, WMGetSystemPixmap(scr, WSIHighlightedReturnArrow));
  1594.     WMSetButtonImagePosition(panel->okB, WIPRight);
  1595.     WMSetButtonAction(panel->okB, okButtonCallback, panel);
  1596.  
  1597.     panel->done = 0;
  1598.  
  1599.     WMCreateEventHandler(WMWidgetView(panel->win), KeyPressMask,
  1600.                          handleKeyPress, panel);
  1601.  
  1602.     WMRealizeWidget(panel->win);
  1603.     WMMapSubwidgets(panel->win);
  1604.  
  1605.     WMMapWidget(panel->win);
  1606.  
  1607.     XSetInputFocus(dpy, WMWidgetXID(panel->win), RevertToParent, CurrentTime);
  1608.  
  1609.     while (!panel->done) {
  1610.         XEvent event;
  1611.  
  1612.         WMNextEvent(dpy, &event);
  1613.         WMHandleEvent(&event);
  1614.     }
  1615.  
  1616.     action = panel->action;
  1617.  
  1618.     WMUnmapWidget(panel->win);
  1619.     WMDestroyWidget(panel->win);
  1620.     free(panel);
  1621.  
  1622.     return action;
  1623. }
  1624.  
  1625.  
  1626.  
  1627.  
  1628. /*****************************************************************************
  1629.  *            About GNUstep Panel
  1630.  *****************************************************************************/
  1631.  
  1632.  
  1633. static void
  1634. drawGNUstepLogo(Display *dpy, Drawable d, int width, int height,
  1635.         unsigned long blackPixel, unsigned long whitePixel)
  1636. {
  1637.     GC gc;
  1638.     XGCValues gcv;
  1639.     XRectangle rects[3];
  1640.  
  1641.     gcv.foreground = blackPixel;
  1642.     gc = XCreateGC(dpy, d, GCForeground, &gcv);
  1643.  
  1644.     XFillArc(dpy, d, gc, width/45, height/45, 
  1645.          width - 2*width/45, height - 2*height/45, 0, 360*64);
  1646.  
  1647.     rects[0].x = 0;
  1648.     rects[0].y = 37*height/45;
  1649.     rects[0].width = width/3;
  1650.     rects[0].height = height - rects[0].y;
  1651.  
  1652.     rects[1].x = rects[0].width;
  1653.     rects[1].y = height/2;
  1654.     rects[1].width = width - 2*width/3;
  1655.     rects[1].height = height - rects[1].y;
  1656.  
  1657.     rects[2].x = 2*width/3;
  1658.     rects[2].y = height - 37*height/45;
  1659.     rects[2].width = width/3;
  1660.     rects[2].height = height - rects[2].y;
  1661.  
  1662.     XSetClipRectangles(dpy, gc, 0, 0, rects, 3, Unsorted);
  1663.     XFillRectangle(dpy, d, gc, 0, 0, width, height);
  1664.  
  1665.     XSetForeground(dpy, gc, whitePixel);
  1666.     XFillArc(dpy, d, gc, width/45, height/45, 
  1667.          width - 2*width/45, height - 2*height/45, 0, 360*64);
  1668.  
  1669.     XFreeGC(dpy, gc);
  1670. }
  1671.  
  1672.  
  1673.  
  1674. #define GNUSTEP_TEXT \
  1675.     "Window Maker is part of the GNUstep project.\n"\
  1676.     "The GNUstep project aims to create a free\n"\
  1677.     "implementation of the OpenStep(tm) specification\n"\
  1678.     "which is a object-oriented framework for\n"\
  1679.     "creating advanced graphical, multi-platform\n"\
  1680.     "applications. Additionally, a development and\n"\
  1681.     "user desktop enviroment will be created on top\n"\
  1682.     "of the framework. For more information about\n"\
  1683.     "GNUstep, please visit: www.gnustep.org"
  1684.  
  1685.  
  1686. typedef struct {
  1687.     WScreen *scr;
  1688.     
  1689.     WWindow *wwin;
  1690.  
  1691.     WMWindow *win;
  1692.  
  1693.     WMLabel *gstepL;
  1694.     WMLabel *textL;
  1695. } GNUstepPanel;
  1696.  
  1697.  
  1698. static GNUstepPanel *gnustepPanel = NULL;
  1699.  
  1700. static void
  1701. destroyGNUstepPanel(WCoreWindow *foo, void *data, XEvent *event)
  1702. {
  1703.     WMUnmapWidget(gnustepPanel->win);
  1704.  
  1705.     WMDestroyWidget(gnustepPanel->win);    
  1706.  
  1707.     wUnmanageWindow(gnustepPanel->wwin, False, False);
  1708.  
  1709.     free(gnustepPanel);
  1710.  
  1711.     gnustepPanel = NULL;
  1712. }
  1713.  
  1714.  
  1715. void
  1716. wShowGNUstepPanel(WScreen *scr)
  1717. {
  1718.     GNUstepPanel *panel;
  1719.     Window parent;
  1720.     WWindow *wwin;
  1721.     WMPixmap *pixmap;
  1722.     WMColor *color;
  1723.  
  1724.     if (gnustepPanel) {
  1725.     if (gnustepPanel->scr == scr) {
  1726.         wRaiseFrame(gnustepPanel->wwin->frame->core);
  1727.         wSetFocusTo(scr, gnustepPanel->wwin);
  1728.     }
  1729.     return;
  1730.     }
  1731.  
  1732.     panel = wmalloc(sizeof(GNUstepPanel));
  1733.  
  1734.     panel->scr = scr;
  1735.  
  1736.     panel->win = WMCreateWindow(scr->wmscreen, "About GNUstep");
  1737.     WMResizeWidget(panel->win, 325, 200);
  1738.  
  1739.     pixmap = WMCreatePixmap(scr->wmscreen, 130, 130, 
  1740.                 WMScreenDepth(scr->wmscreen), True);
  1741.  
  1742.     color = WMCreateNamedColor(scr->wmscreen, "gray50", True);
  1743.  
  1744.     drawGNUstepLogo(dpy, WMGetPixmapXID(pixmap), 130, 130,
  1745.             WMColorPixel(color), scr->white_pixel);
  1746.  
  1747.     WMReleaseColor(color);
  1748.  
  1749.     XSetForeground(dpy, scr->mono_gc, 0);
  1750.     XFillRectangle(dpy, WMGetPixmapMaskXID(pixmap), scr->mono_gc, 0, 0, 
  1751.            130, 130);
  1752.     drawGNUstepLogo(dpy, WMGetPixmapMaskXID(pixmap), 130, 130, 1, 1);
  1753.  
  1754.     panel->gstepL = WMCreateLabel(panel->win);
  1755.     WMResizeWidget(panel->gstepL, 285, 64);
  1756.     WMMoveWidget(panel->gstepL, 20, 0);
  1757.     WMSetLabelTextAlignment(panel->gstepL, WARight);
  1758.     WMSetLabelText(panel->gstepL, "GNUstep");
  1759.     {
  1760.     WMFont *font = WMBoldSystemFontOfSize(scr->wmscreen, 24);
  1761.  
  1762.     WMSetLabelFont(panel->gstepL, font);
  1763.     WMReleaseFont(font);
  1764.     }
  1765.  
  1766.     panel->textL = WMCreateLabel(panel->win);
  1767.     WMResizeWidget(panel->textL, 275, 130);
  1768.     WMMoveWidget(panel->textL, 30, 50);
  1769.     WMSetLabelTextAlignment(panel->textL, WARight);
  1770.     WMSetLabelImagePosition(panel->textL, WIPOverlaps);
  1771.     WMSetLabelText(panel->textL, GNUSTEP_TEXT);
  1772.     WMSetLabelImage(panel->textL, pixmap);
  1773.  
  1774.     WMReleasePixmap(pixmap);
  1775.  
  1776.     WMRealizeWidget(panel->win);
  1777.     WMMapSubwidgets(panel->win);
  1778.  
  1779.     parent = XCreateSimpleWindow(dpy, scr->root_win, 0, 0, 325, 200, 0, 0, 0);
  1780.  
  1781.     XReparentWindow(dpy, WMWidgetXID(panel->win), parent, 0, 0);
  1782.  
  1783.     wwin = wManageInternalWindow(scr, parent, None, "About GNUstep",
  1784.                  (scr->scr_width - 325)/2,
  1785.                  (scr->scr_height - 200)/2, 325, 200);
  1786.  
  1787.     WSETUFLAG(wwin, no_closable, 0);
  1788.     WSETUFLAG(wwin, no_close_button, 0);
  1789.     wWindowUpdateButtonImages(wwin);
  1790.     wFrameWindowShowButton(wwin->frame, WFF_RIGHT_BUTTON);
  1791. #ifdef XKB_BUTTON_HINT
  1792.     wFrameWindowHideButton(wwin->frame, WFF_LANGUAGE_BUTTON);
  1793. #endif
  1794.     wwin->frame->on_click_right = destroyGNUstepPanel;
  1795.     
  1796.     panel->wwin = wwin;
  1797.     
  1798.     WMMapWidget(panel->win);
  1799.  
  1800.     wWindowMap(wwin);
  1801.  
  1802.     gnustepPanel = panel;
  1803. }
  1804.